/*
 * Copyright (c) 2020-2099 the original author or authors. All rights reserve.
 */
package org.tianyun.cloud.mybatis.plugins.utils;

import org.apache.ibatis.mapping.BoundSql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tianyun.cloud.mybatis.plugins.MybatisPagePlugin;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * PluginAcessUtils
 *
 * @auther ebert_chan
 */
public class AcessUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(MybatisPagePlugin.class);

    private static Field BOUNDSQL_ADDITIONALPARAMETERS_FIELD;

    private static Field BOUNDSQL_SQL_FIELD;

    static {
        try {
            BOUNDSQL_ADDITIONALPARAMETERS_FIELD = BoundSql.class.getDeclaredField("additionalParameters");
            BOUNDSQL_ADDITIONALPARAMETERS_FIELD.setAccessible(true);

            BOUNDSQL_SQL_FIELD = BoundSql.class.getDeclaredField("sql");
            BOUNDSQL_SQL_FIELD.setAccessible(true);
        } catch (NoSuchFieldException e) {
            LOGGER.error("An exception occurred.", e);
        } catch (SecurityException e) {
            LOGGER.error("An exception occurred.", e);
        }
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> getAdditionalParameter(BoundSql boundSql) {
        try {
            return (Map<String, Object>) BOUNDSQL_ADDITIONALPARAMETERS_FIELD.get(boundSql);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            LOGGER.error("An exception occurred.", e);
        }
        return null;
    }

    public static void setSql(BoundSql target, String sql) {
        try {
            BOUNDSQL_SQL_FIELD.set(target, sql);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            LOGGER.error("An exception occurred.", e);
        }
    }

    public static void copyAdditionalParameters(BoundSql source, BoundSql target) {
        Map<String, Object> additionalParameters = AcessUtils.getAdditionalParameter(source);
        if (additionalParameters != null) {
            for (String key : additionalParameters.keySet()) {
                target.setAdditionalParameter(key, additionalParameters.get(key));
            }
        }
    }

}
